// ignore_for_file: use_build_context_synchronously, library_private_types_in_public_api

import 'dart:convert';
import 'dart:io';

import 'package:encrypt_and_decrypt_files/dio_util.dart';
import 'package:encrypt_and_decrypt_files/encrypt_page/algorithm.dart';
import 'package:encrypt_and_decrypt_files/my/key_management_page.dart';
import 'package:encrypt_and_decrypt_files/widget/extension.dart';
import 'package:encrypt_and_decrypt_files/widget/theme_provider.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flustars_flutter3/flustars_flutter3.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:intl/intl.dart';
import 'package:local_auth/local_auth.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';

class EncryptDecryptPage extends StatefulWidget {
  final bool isEncrypting; // true: 加密, false: 解密

  const EncryptDecryptPage({super.key, required this.isEncrypting});

  @override
  _EncryptDecryptPageState createState() => _EncryptDecryptPageState();
}

class _EncryptDecryptPageState extends State<EncryptDecryptPage> {
  SecretKeyModel? secretKeyModel;

  List<File> selectedFiles = [];
  List<String> showSelectedFiles = [];
  String selectedAlgorithm = 'AES';
  List<String> algorithms = ['AES', 'RC2', 'RC4'];
  String selectedFileType = 'dat';
  List<String> fileType = [
    'png',
    'dat',
    'jpg',
    'mp3',
    'mp4',
    'avi',
    'wav',
    'flac',
    'wv',
    'zip',
    'doc',
    'xls',
    'ppt',
    'xlsx',
    'docx',
    'pdf',
    'txt',
    'rar',
    '7z',
    'tar',
    'gz',
  ];

  Uint8List? key;

  @override
  void initState() {
    super.initState();
  }

  void _selectFiles() async {
    FilePickerResult? result =
        await FilePicker.platform.pickFiles(allowMultiple: true);

    if (result != null) {
      setState(() {
        selectedFiles = result.paths.map((path) => File(path!)).toList();
        showSelectedFiles =
            result.paths.map((path) => path!.split('/').last).toList();
      });
    }
  }

  void _startProcess() async {
    if (selectedFiles.isEmpty) {
      Fluttertoast.showToast(msg: 'Please select the file first'.t(context));
      return;
    }
    if (key == null) {
      Fluttertoast.showToast(msg: 'Please select one key first'.t(context));
      return;
    }

    var status = await Permission.manageExternalStorage.status;
    if (!status.isGranted) {
      await Permission.manageExternalStorage.request();
    }
    try {
      final _localAuth = LocalAuthentication();

      bool isAuthenticated = await _localAuth.authenticate(
        localizedReason: '请验证您的指纹',
        options: const AuthenticationOptions(stickyAuth: true),
      );

      if (!isAuthenticated) {
        // 验证失败，显示提示
        Fluttertoast.showToast(msg: 'Authentication failure'.t(context));
        return;
      }
    } catch (e) {
      Fluttertoast.showToast(msg: 'Authentication failure'.t(context));
      return;
    }
    for (var file in selectedFiles) {
      // 设置目标目录为公共的Download目录
      String newDirPath = '';
      if (widget.isEncrypting) {
        newDirPath = '/storage/emulated/0/Download/encrypt';
      } else {
        newDirPath = '/storage/emulated/0/Download/decrypt';
      }
      final newDir = Directory(newDirPath);

      if (!await newDir.exists()) {
        await newDir.create(recursive: true); // 创建目录
      }

      // 获取原始文件的后缀
      final extension = file.path.split('.').last;
      // 创建没有后缀的新文件名
      final baseName = file.path.split('/').last.replaceAll('.$extension', '');
      // 获取当前的时间戳
      final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
      // 构造新的文件路径
      final newFileName =
          '$baseName(${widget.isEncrypting ? "Encrypt" : "Decrypt"})_$timestamp.${widget.isEncrypting ? "dat" : selectedFileType}';
      final newFilePath = '${newDir.path}/$newFileName';
      bool? a = await Algorithm().encrypt(
        context: context,
        name: selectedAlgorithm,
        type: widget.isEncrypting ? 0 : 1,
        inputFile: file.path,
        encryptedFile: widget.isEncrypting ? newFilePath : null,
        decryptedFile: widget.isEncrypting ? null : newFilePath,
        key: key!,
        iv: key, // 确保这里传递的是正确的IV
      );
      if (a != false) {
        _recordProcessing(RecordProcessingModel(
          type: widget.isEncrypting ? 'encrypt' : 'decrypt',
          originDir: file.path,
          originFile: file.path.split('/').last,
          destDir: newDir.path,
          destFile: newFileName,
          algorithm: selectedAlgorithm,
          key: secretKeyModel?.key.toString(),
          name: secretKeyModel?.name,
          dateTime: DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now()),
        ));
      }
    }
    Fluttertoast.showToast(msg: 'Processing completed'.t(context));
  }

  @override
  Widget build(BuildContext context) {
    final themeProvider = Provider.of<ThemeProvider>(context);

    return Scaffold(
      appBar: AppBar(
        backgroundColor: themeProvider.mainColor,
        centerTitle: true,
        title: Text(
            widget.isEncrypting ? 'Encrypt'.t(context) : 'Decrypt'.t(context)),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            ElevatedButton(
              onPressed: _selectFiles,
              child: Text('Select files'.t(context)),
            ),
            Expanded(
              child: ListView.builder(
                itemCount: showSelectedFiles.length,
                itemBuilder: (context, index) {
                  return ListTile(
                    title: Text(showSelectedFiles[index]),
                  );
                },
              ),
            ),
            Row(
              children: [
                Text('Select algorithm'.t(context)),
                const SizedBox(width: 15),
                DropdownButton<String>(
                  value: selectedAlgorithm,
                  items: algorithms
                      .map((algo) => DropdownMenuItem(
                            value: algo,
                            child: Text(algo),
                          ))
                      .toList(),
                  onChanged: (value) {
                    setState(() {
                      selectedAlgorithm = value!;
                    });
                  },
                ),
              ],
            ),
            if (!widget.isEncrypting)
              Row(
                children: [
                  Text('Select fileType'.t(context)),
                  const SizedBox(width: 15),
                  DropdownButton<String>(
                    value: selectedFileType,
                    items: fileType
                        .map((algo) => DropdownMenuItem(
                              value: algo,
                              child: Text(algo),
                            ))
                        .toList(),
                    onChanged: (value) {
                      setState(() {
                        selectedFileType = value!;
                      });
                    },
                  ),
                ],
              ),
            Row(
              children: [
                Text('Select key'.t(context)),
                const SizedBox(width: 15),
                if (secretKeyModel != null) ...[
                  Text(secretKeyModel!.name!),
                  const SizedBox(width: 15),
                ],
                ElevatedButton(
                  onPressed: () async {
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) => KeyManagementPage(
                                isSelected: true,
                                onConfirm: (model) {
                                  setState(() {
                                    secretKeyModel = model;
                                    key = Uint8List.fromList(
                                        secretKeyModel!.key!.codeUnits);
                                  });
                                },
                              )),
                    );
                  },
                  child: Text('Select Key'.t(context)),
                ),
              ],
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: _startProcess,
              child: Text('Start'.t(context)),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _recordProcessing(
    RecordProcessingModel model,
  ) async {
    const url = '/record_processing';
    String token = SpUtil.getString('token') ?? '';
    var response = await DioHttp.of(context).post(url, model.toJson(), token);
    var resString = json.decode(response.toString());

    if (resString['code'] == 200) {
    } else {
      Fluttertoast.showToast(msg: resString['msg']);
    }
  }
}

class RecordProcessingModel {
  String? type;
  String? originDir;
  String? originFile;
  String? destDir;
  String? destFile;
  String? algorithm;
  String? key;
  String? name;
  String? dateTime;
  int? id;

  RecordProcessingModel({
    this.type,
    this.originDir,
    this.originFile,
    this.destDir,
    this.destFile,
    this.algorithm,
    this.key,
    this.name,
    this.dateTime,
    this.id,
  });

  Map<String, dynamic> toJson() {
    final map = <String, dynamic>{};
    map['type'] = type;
    map['originDir'] = originDir;
    map['originFile'] = originFile;
    map['destDir'] = destDir;
    map['destFile'] = destFile;
    map['algorithm'] = algorithm;
    map['key'] = key;
    map['name'] = name;
    map['dateTime'] = dateTime;
    map['id'] = id;
    return map;
  }

  factory RecordProcessingModel.fromJson(Map<String, dynamic> json) =>
      RecordProcessingModel()
        ..type = json['type'] as String?
        ..originDir = json['originDir'] as String?
        ..originFile = json['originFile'] as String?
        ..destDir = json['destDir'] as String?
        ..destFile = json['destFile'] as String?
        ..algorithm = json['algorithm'] as String?
        ..key = json['key'] as String?
        ..name = json['name'] as String?
        ..id = json['id'] as int?
        ..dateTime = json['dateTime'] as String?;
}
